/** Header **/

#include <string.h>

#include "messages/Response.h"

namespace SAYL {

/** Data **/


/**********************************************************************************************
 * Constructor
 *********************************************************************************************/
ResponseData::ResponseData (std::string __address, int __port, int __piecesize)
  : Response (__address, __port), piecesize (0)
{
  if (__piecesize > 0) piecesize = __piecesize;
}

/**********************************************************************************************
 * Destructor
 *********************************************************************************************/
ResponseData::~ResponseData () {
  int count = pieces.size ();
  for (int index = 0; index < count; index++) {
    if (pieces [index].content != (uint8_t *) 0) {
      delete [] pieces [index].content;
    }
  }
}

/**********************************************************************************************
 * getPieceSize
 *********************************************************************************************/
int ResponseData::getPieceSize () const {
  return piecesize;
}

/**********************************************************************************************
 * getKey
 *********************************************************************************************/
std::string ResponseData::getKey () const {
  return key;
}
  
/**********************************************************************************************
 * setKey
 *********************************************************************************************/
void ResponseData::setKey (std::string __key) {
  key = __key;
}

/**********************************************************************************************
 * getPieceCount
 *********************************************************************************************/
int ResponseData::getPieceCount () const {
  return pieces.size ();
}

/**********************************************************************************************
 * getPieceIndex
 *********************************************************************************************/
int ResponseData::getPieceIndex (int index) const {
  return pieces.at (index).index;
}

/**********************************************************************************************
 * getPieceData
 *********************************************************************************************/
const uint8_t * ResponseData::getPieceData (int index) const {
  return pieces.at (index).content;
}
  
/**********************************************************************************************
 * addPiece
 *********************************************************************************************/
bool ResponseData::addPiece (int index, uint8_t * content) {
  if (piecesize > 0) {
    Piece piece;

    piece.content = new uint8_t [piecesize];
    if (piece.content == (uint8_t *) 0) 
      return false;
    piece.index = index;
    memcpy (piece.content, content, piecesize);
    pieces.push_back (piece);

    return true;
  } else {
    return false;
  }
}


/** Have **/


/**********************************************************************************************
 * Constructor
 *********************************************************************************************/
ResponseHave::ResponseHave (std::string __address, int __port, int __size)
  : Response (__address, __port), size (0), buffermap ((uint8_t *) 0)
{
  if (__size > 0) {
    size = __size;
    buffermap = new uint8_t [size];
    bzero ((void *) buffermap, size);
  }
}

/**********************************************************************************************
 * Destructor
 *********************************************************************************************/
ResponseHave::~ResponseHave () {
  if (buffermap != (uint8_t *) 0) {
    delete [] buffermap;
  }
}

/**********************************************************************************************
 * getKey
 *********************************************************************************************/
std::string ResponseHave::getKey () const {
  return key;
}
  
/**********************************************************************************************
 * setKey
 *********************************************************************************************/
void ResponseHave::setKey (std::string __key) {
  key = __key;
}

/**********************************************************************************************
 * getBufferMapSize
 *********************************************************************************************/
int ResponseHave::getBufferMapSize () const {
  return size;
}

/**********************************************************************************************
 * getBufferMap
 *********************************************************************************************/
const uint8_t * ResponseHave::getBufferMap () const {
  return buffermap;
}
  
/**********************************************************************************************
 * setBufferMap
 *********************************************************************************************/
bool ResponseHave::setBufferMap (uint8_t * buffer) {
  if (buffermap != (uint8_t *) 0) {
    memcpy (buffermap, buffer, size);
    return true;
  } else {
    return false;
  }
}


/** List **/

/**********************************************************************************************
 * getFileCount
 *********************************************************************************************/
int ResponseList::getFileCount () const {
  return files.size ();
}

/**********************************************************************************************
 * getFileName
 *********************************************************************************************/
std::string ResponseList::getFileName (int index) const {
  return files.at (index).filename;
}
  
/**********************************************************************************************
 * getFileKey
 *********************************************************************************************/
std::string ResponseList::getFileKey (int index) const {
  return files.at (index).key;
}
  
/**********************************************************************************************
 * getFileSize
 *********************************************************************************************/
long ResponseList::getFileSize (int index) const {
  return files.at (index).piecesize;
}
  
/**********************************************************************************************
 * getFilePieceSize
 *********************************************************************************************/
long ResponseList::getFilePieceSize (int index) const {
  return files.at (index).filesize;
}
  
/**********************************************************************************************
 * addFile
 *********************************************************************************************/
void ResponseList::addFile (std::string filename, std::string key, long size, long piecesize) {
  FileInfo __fileinfo;
  __fileinfo.filename = filename;
  __fileinfo.key = key;
  __fileinfo.filesize = size;
  __fileinfo.piecesize = piecesize;
  files.push_back (__fileinfo);
}

/** Peers **/

/**********************************************************************************************
 * getKey
 *********************************************************************************************/
std::string ResponsePeers::getKey () const {
  return key;
}
  
/**********************************************************************************************
 * setKey
 *********************************************************************************************/
void ResponsePeers::setKey (std::string __key) {
  key = __key;
}

/**********************************************************************************************
 * getPeerCount
 *********************************************************************************************/
int ResponsePeers::getPeersCount () const {
  return peers.size ();
}
  
/**********************************************************************************************
 * getPeerAddress
 *********************************************************************************************/
std::string ResponsePeers::getPeerAddress (int index) const {
  return peers.at (index).address;
}
  
/**********************************************************************************************
 * getPeerPort
 *********************************************************************************************/
int ResponsePeers::getPeerPort (int index) const {
  return peers.at (index).port;
}
  
/**********************************************************************************************
 * addPeed
 *********************************************************************************************/
void ResponsePeers::addPeer (std::string address, int port) {
  PeerInfo peer;
  peer.address = address;
  peer.port = port;
  peers.push_back (peer);
}


} // namespace SAYL

